package com.tmsps.ne4weixin.action;

import java.util.Map;

import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.tmsps.ne4weixin.bean.message.event.BaseEvent;
import com.tmsps.ne4weixin.bean.message.event.LocationEvent;
import com.tmsps.ne4weixin.bean.message.event.MenuEvent;
import com.tmsps.ne4weixin.bean.message.event.QrsceneEvent;
import com.tmsps.ne4weixin.bean.message.event.SubscribeEvent;
import com.tmsps.ne4weixin.bean.message.receive.ImageMessageVo;
import com.tmsps.ne4weixin.bean.message.receive.InBaseMessage;
import com.tmsps.ne4weixin.bean.message.receive.LinkMessageVo;
import com.tmsps.ne4weixin.bean.message.receive.LocationMessageVo;
import com.tmsps.ne4weixin.bean.message.receive.ShortVideoMessageVo;
import com.tmsps.ne4weixin.bean.message.receive.TextMessageVo;
import com.tmsps.ne4weixin.bean.message.receive.VideoMessageVo;
import com.tmsps.ne4weixin.bean.message.receive.VoiceMessageVo;
import com.tmsps.ne4weixin.config.WxConfig;
import com.tmsps.ne4weixin.config.enumeration.EventTypeEnum;
import com.tmsps.ne4weixin.config.enumeration.MsgTypeEnum;
import com.tmsps.ne4weixin.utils.WXUtil;
import com.tmsps.ne4weixin.utils.WeiXinMsgUtil;
import com.tmsps.ne4weixin.utils.XmlUtils;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public abstract class Ne4WeiXinSpringAction extends WeixinSupport {
	/**
	 * request and resopnse
	 */
	protected HttpServletRequest request;
	protected HttpServletResponse response;

	@ModelAttribute
	public void setRequestAndResopnse(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}

	/**
	 * @Title: getWxConfig 
	 * @Description: 根据识别码来判断不同的微信服务号信息 
	 * @author:zhangwei 
	 * @date: Mar 9, 2020 1:48:15 PM 
	 */
	public abstract WxConfig getWxConfig();

	/**
	 * @Title: bind 
	 * @Description: 微信服务器与应用服务器通信绑定 
	 * @author:zhangwei 
	 * @date: Mar 9, 2020 11:50:54 AM 
	 */
	@RequestMapping(method = RequestMethod.GET)
	public String bind() {
		if (WXUtil.isCheck(request, getWxConfig().getToken())) {
			// 绑定微信服务器成功
			String echostr = request.getParameter("echostr");
			log.info("bind weixin server success , and echostr is {}", echostr);
			return echostr;
		} else {
			// 绑定微信服务器失败
			log.warn("bind weixin server faile !!!");
		}
		return "";
	}

	@RequestMapping(method = RequestMethod.POST)
	public String handle(@RequestBody String body) {
		log.info("The message is {}", body);
		if (WXUtil.isCheck(request, getWxConfig().getToken())) {// 如果信息来源于微信服务器则继续处理
			log.info("----------消息验证通过是来自微信服务器通信，开始解密微信消息----------");
			String message = WXUtil.decryptMsg(request, getWxConfig(), body);
			log.info(" \n---=== 解密后的消息 ===--- \n{}\n---=== 请根据业务进行后续处理 ===---", message);
			Map<String, String> xmlMap = XmlUtils.getXmlToMap(message);
			//消息类型
			String MsgType = WeiXinMsgUtil.getMsgType(xmlMap);
			//如果消息是event事件
			if (MsgType.equals(EventTypeEnum.Event.toName())) {
				BaseEvent baseEvent = WeiXinMsgUtil.toEventBean(xmlMap);
				log.info("封装的event :{}", baseEvent);

				if (baseEvent instanceof SubscribeEvent) {
					return processInSubscribeEvent((SubscribeEvent) baseEvent);
				}
				if (baseEvent instanceof QrsceneEvent) {
					return processInQrsceneEvent((QrsceneEvent) baseEvent);
				}
				if (baseEvent instanceof LocationEvent) {
					return processInLocationEvent((LocationEvent) baseEvent);
				}
				if (baseEvent instanceof MenuEvent) {
					return processInMenuEvent((MenuEvent) baseEvent);
				}

			} else {
				// 封装为微信消息实体类
				InBaseMessage baseMessage = WeiXinMsgUtil.toMessageBean(xmlMap);
				// 处理接受到的文本消息
				if (MsgType.equals(MsgTypeEnum.IMAGE.toName())) {
					return processInImageMsg((ImageMessageVo) baseMessage);
				}
				if (MsgType.equals(MsgTypeEnum.LINK.toName())) {
					return processInLinkMsg((LinkMessageVo) baseMessage);
				}
				if (MsgType.equals(MsgTypeEnum.LOCATION.toName())) {
					return processInLocationMsg((LocationMessageVo) baseMessage);
				}
				if (MsgType.equals(MsgTypeEnum.SHORT_VIDEO.toName())) {
					return processInShortVideoMsg((ShortVideoMessageVo) baseMessage);
				}
				if (MsgType.equals(MsgTypeEnum.TEXT.toName())) {
					return processInTextMsg((TextMessageVo) baseMessage);
				}
				if (MsgType.equals(MsgTypeEnum.VIDEO.toName())) {
					return processInVideoMsg((VideoMessageVo) baseMessage);
				}
				if (MsgType.equals(MsgTypeEnum.VOICE.toName())) {
					return processInVoiceMsg((VoiceMessageVo) baseMessage);
				}
			}

		} else {
			log.warn("接收到来自非微信验证服务器的信息，已经被丢弃:{}", body);
		}
		return null;
	}
	
	// 处理接收到的图片消息
	protected abstract String processInImageMsg(ImageMessageVo ImageMessage);
	// 处理接收到的链接消息
	protected abstract String processInLinkMsg(LinkMessageVo LinkMessage);
	// 处理接收到的位置消息
	protected abstract String processInLocationMsg(LocationMessageVo LocationMessage);
	// 处理接收到的短视频消息
	protected abstract String processInShortVideoMsg(ShortVideoMessageVo ShortVideoMessage);
	// 处理接收到的文本消息
	protected abstract String processInTextMsg(TextMessageVo TextMessage);
	// 处理接收到的视频消息
	protected abstract String processInVideoMsg(VideoMessageVo VideoMessage);
	// 处理接收到的语音消息
	protected abstract String processInVoiceMsg(VoiceMessageVo VoiceMessage);
	/**
	 * 处理接收到的事件信息
	 */
	//关注事件
	protected abstract String processInSubscribeEvent(SubscribeEvent subscribeEvent);
	//扫码事件
	protected abstract String processInQrsceneEvent(QrsceneEvent qrsceneEvent);
	//地理位置上报事件
	protected abstract String processInLocationEvent(LocationEvent locationEvent);
	//自定义菜单事件
	protected abstract String processInMenuEvent(MenuEvent menuEvent);
	
}
